package cn.maihe.elg.operation.web.guarantee;

import cn.maihe.elg.operation.config.TemplateUploadConfig;
import cn.maihe.elg.operation.exception.ErrorCode;
import cn.maihe.elg.operation.exception.SystemRuntimeException;
import cn.maihe.elg.operation.model.enums.OpenCloseEnum;
import cn.maihe.elg.operation.model.enums.UserType;
import cn.maihe.elg.operation.model.vo.guarantee.*;
import cn.maihe.elg.operation.repository.entity.GuaranteeTemplateDO;
import cn.maihe.elg.operation.repository.entity.GuaranteeTemplateDOCondition;
import cn.maihe.elg.operation.repository.entity.GuaranteeTemplateVo;
import cn.maihe.elg.operation.security.model.UserContext;
import cn.maihe.elg.operation.service.guarantee.GuaranteeTemplateService;
import cn.maihe.elg.operation.utils.IdGenerate;
import cn.maihe.elg.operation.utils.UserContextUtil;
import cn.maihe.framework.starter.base.sql.PageBo;
import com.alibaba.fastjson.JSONObject;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.file.Paths;
import java.util.List;

/**
 * @Description 保函电子模板controller
 * @Author caixh
 * @Date 2021/4/14.
 */
@Api(value = "保函电子模板管理", tags = "保函电子模板管理")
@RestController
@RequestMapping("/api")
@Slf4j
public class GuaranteeTemplateController {
    @Resource
    private GuaranteeTemplateService guaranteeTemplateService;
    @Resource
    private TemplateUploadConfig templateUploadConfig;

    @ApiOperation(value = "分页查询保函电子模板", notes = "根据保函电子模板类型、机构编码、机构名称 分页查询")
    @RequestMapping(value = "/guaranteeTemplates", method = RequestMethod.GET)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNo", value = "页数", dataType = "int", paramType = "query", required = true),
            @ApiImplicitParam(name = "pageSize", value = "每页大小", dataType = "int", paramType = "query", required = true),
            @ApiImplicitParam(name = "guaranteeType", value = "保函电子模板类型", dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "guaranteeCategory", value = "保函品种", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "templateName", value = "保函电子模板名称", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "gmtCreateRange", value = "创建时间（startDate,endDate）", dataType = "String", paramType = "query")
    })
    public PageBo<TemplateVO> pageList(int pageNo, int pageSize, String gmtCreateRange, GuaranteeTemplateVo vo) {
        //登录机构过滤
        UserContext uc = UserContextUtil.getUserContext();
        if (UserType.GENERAL.getType() != uc.getUserType()) {
            vo.setOrgId(uc.getOrgId());
        }
        return guaranteeTemplateService.selectPageBySql(pageNo, pageSize, gmtCreateRange, vo);
    }

    @ApiOperation(value = "获取保函电子模板", notes = "根据保函电子模板id获取保函电子模板")
    @ApiImplicitParam(name = "id", value = "保函电子模板id", dataType = "long", paramType = "path", required = true)
    @RequestMapping(value = "/guaranteeTemplate/{id}", method = RequestMethod.GET)
    public GuaranteeTemplateDO getTemplate(@PathVariable Long id) {
        GuaranteeTemplateDO curDO = guaranteeTemplateService.selectById(id);
        if (curDO == null) {
            throw new SystemRuntimeException(ErrorCode.NOTEXISTS, "保函电子模板id");
        }
        return curDO;
    }

    @ApiOperation(value = "新增保函电子模板", notes = "新增保函电子模板")
    @RequestMapping(value = "/guaranteeTemplate", method = RequestMethod.POST)
    public void createTemplate(@Validated @RequestBody CreateTemplateVO vo) {
        GuaranteeTemplateDO cDO = new GuaranteeTemplateDO();
        BeanUtils.copyProperties(vo, cDO);
        cDO.setId(IdGenerate.getId());

        // 登录机构设置
        UserContext uc = UserContextUtil.getUserContext();
        if (UserType.GENERAL.getType() != uc.getUserType()) {
            cDO.setOrgId(uc.getOrgId());
        } else {
            //运营机构不能提交保函模板
            throw new SystemRuntimeException(ErrorCode.TEMP001);
        }
        cDO.setStatus(OpenCloseEnum.CLOSED.getValue());

        if (guaranteeTemplateService.exists(GuaranteeTemplateDOCondition.builder().andTemplateNameEq(vo.getTemplateName()).build())) {
            throw new SystemRuntimeException(ErrorCode.EXISTS, "保函电子模板名称", vo.getTemplateName());
        }
        guaranteeTemplateService.insert(cDO);
    }


    @ApiOperation(value = "保函电子模板预览下载", notes = "根据保函电子模板id预览保函电子模板")
    @RequestMapping(value = "/guaranteeTemplate/view", method = RequestMethod.POST)
    public String view(@Validated @RequestBody UpdateTemplateStatusVO vo, HttpServletResponse response) throws UnsupportedEncodingException {
        GuaranteeTemplateDO mDO = guaranteeTemplateService.selectById(vo.getId());
        String content = mDO.getContent();
        JSONObject contentJO = JSONObject.parseObject(content);

        File file = new File(templateUploadConfig.getPath() + contentJO.getString("url"));
        if (!file.exists()) {
            return "下载文件不存在";
        }
        TemplateOrderVO templateOrderVO = TemplateOrderVO.demo();
        try (FileInputStream in = new FileInputStream(file)) {

            Configure spelConfigure = Configure.newBuilder().setElMode(Configure.ELMode.SPEL_MODE).build();
            XWPFTemplate template = XWPFTemplate.compile(in, spelConfigure).render(
                    templateOrderVO);
            //response.setContentType("application/msword");
            response.setContentType("application/octet-stream");
            response.setCharacterEncoding("utf-8");
            String fileName = contentJO.getString("name");
            fileName = URLEncoder.encode(fileName, "utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            template.write(response.getOutputStream());
        } catch (IOException e) {
            log.error("下载失败", e);
            return "下载失败";
        }
        return "";

    }

    @ApiOperation(value = "保函电子模板下载", notes = "根据保函电子模板id下载保函电子模板")
    @RequestMapping(value = "/guaranteeTemplate/download", method = RequestMethod.POST)
    public String download(@Validated @RequestBody UpdateTemplateStatusVO vo, HttpServletResponse response) throws UnsupportedEncodingException {
        GuaranteeTemplateDO mDO = guaranteeTemplateService.selectById(vo.getId());
        String content = mDO.getContent();
        JSONObject contentJO = JSONObject.parseObject(content);
        response.setContentType("application/octet-stream");

        File file = Paths.get(templateUploadConfig.getPath(), contentJO.getString("url")).toFile();
        if (!file.exists()) {
            return "下载文件不存在";
        }
        response.setCharacterEncoding("utf-8");
        response.setContentLength((int) file.length());
        response.setHeader("Content-Disposition", "attachment; fileName=" + contentJO.getString("name") + ";filename*=utf-8''" + URLEncoder.encode(contentJO.getString("name"), "UTF-8"));
        //解决文件名中文问题

        try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file))) {
            byte[] buff = new byte[1024];
            OutputStream os = response.getOutputStream();
            int i = 0;
            while ((i = bis.read(buff)) != -1) {
                os.write(buff, 0, i);
                os.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
            return "下载失败";
        }
        return "下载成功";
    }

    @ApiOperation(value = "保函电子模板启用设置", notes = "根据保函电子模板id设置保函电子模板启用状态")
    @RequestMapping(value = "/guaranteeTemplate/openClose", method = RequestMethod.PUT)
    public void openCloseTemplate(@Validated @RequestBody UpdateTemplateStatusVO vo) {
        GuaranteeTemplateDO mDO = new GuaranteeTemplateDO();
        BeanUtils.copyProperties(vo, mDO);
        guaranteeTemplateService.updateById(mDO);
    }

    @ApiOperation(value = "修改保函电子模板", notes = "根据保函电子模板id修改保函电子模板")
    @RequestMapping(value = "/guaranteeTemplate", method = RequestMethod.PUT)
    public void modifyTemplate(@Validated @RequestBody UpdateTemplateVO vo) {
        GuaranteeTemplateDO mDO = new GuaranteeTemplateDO();
        BeanUtils.copyProperties(vo, mDO);

        if (guaranteeTemplateService.exists(GuaranteeTemplateDOCondition.builder().andTemplateNameEq(vo.getTemplateName()).andIdNe(vo.getId()).build())) {
            throw new SystemRuntimeException(ErrorCode.EXISTS, "保函电子模板名称", vo.getTemplateName());
        }
        guaranteeTemplateService.updateById(mDO);
    }

    @ApiOperation(value = "删除保函电子模板", notes = "根据保函电子模板id删除保函电子模板")
    @ApiImplicitParam(name = "id", value = "保函电子模板id", dataType = "long", paramType = "path", required = true)
    @RequestMapping(value = "/guaranteeTemplate/{id}", method = RequestMethod.DELETE)
    public void deleteTemplate(@PathVariable Long id) {
        guaranteeTemplateService.deleteById(id);
    }


    @ApiOperation(value = "获取保函电子模板列表", notes = "根据机构id及保函类型&品种获取保函列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orgId", value = "机构Id", dataType = "long", paramType = "query", required = true),
            @ApiImplicitParam(name = "guaranteeType", value = "保函类型", dataType = "string", paramType = "query", required = true),
            @ApiImplicitParam(name = "guaranteeCategory", value = "保函品种", dataType = "string", paramType = "query", required = true)
    })
    @RequestMapping(value = "/guaranteeTemplate/selectList", method = RequestMethod.GET)
    public List<GuaranteeTemplateDO> selectList(GuaranteeTemplateVo vo) {
        if (vo == null || vo.getOrgId() == null || vo.getGuaranteeType() == null || vo.getGuaranteeCategory() == null) {
            throw new SystemRuntimeException(ErrorCode.BSMCM001);
        }
        GuaranteeTemplateDOCondition condition = GuaranteeTemplateDOCondition.builder()
                .andOrgIdEq(vo.getOrgId()).andGuaranteeTypeEq(vo.getGuaranteeType()).andGuaranteeCategoryEq(vo.getGuaranteeCategory());
        if (vo.getStatus() != null) {
            condition.andStatusEq(vo.getStatus());
        }
        List<GuaranteeTemplateDO> list = guaranteeTemplateService.selectList(condition.build());

        return list;
    }

}
